/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package edu.pdx.cs.guavadata.condition;

import edu.pdx.cs.guavadata.data.Common;
import edu.pdx.cs.guavadata.domain.Domain;
import edu.pdx.cs.guavadata.subclass.ConditionType;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 *
 * @author VuTran
 */
public class BETCond extends Condition {
    private Object arg1;
    private Object arg2;

    public BETCond(List<Object> args) throws ConditionException {
        if (args.size() != getNumArgs())
            throw new ConditionException("You have specified the wrong number of conditions (" + args.size() + ") for an equality predicate.", getNumArgs());
        arg1 = args.get(0);
        arg2 = args.get(1);
    }

    @Override
    public String toString() {
        return " BETWEEN " + Common.wrap(arg1) + " AND " + Common.wrap(arg2);
    }

    @Override
    public ConditionType getCondType() {
        return ConditionType.BETWEEN;
    }

    @Override
    public final int getNumArgs() {
        return 2;
    }

    @Override
    public List<Object> getArgs() {
        List<Object> lo = new ArrayList<Object>(getNumArgs());
        lo.add(arg1);
        lo.add(arg2);
        return lo;
    }

    @Override
    public boolean equals(Object obj) {
        return ((obj instanceof BETCond) && ((BETCond) obj).arg1.equals(arg1) && ((BETCond) obj).arg2.equals(arg2));
    }

    @Override
    public int hashCode() {
        return this.getClass().hashCode() +  arg1.hashCode() * arg2.hashCode();
    }

    @Override
    public boolean getNeedsOrdered() {
        return true;
    }

    @Override
    public boolean getNeedsContain() {
        return false;
    }

    @Override
    public boolean Validate(Object obj, Domain d) {
        if (d.toString().equals("TinyInteger")) {
            return (((Byte) obj) > ((Byte) arg1)) && (((Byte) obj) < ((Byte) arg2));
        } else if (d.toString().equals("SmallInteger")) {
            return (((Short) obj) > ((Short) arg1)) && (((Short) obj) < ((Short) arg2));
        } else if (d.toString().equals("Integer") || d.toString().equals("IntegerInterval")) {
            return (((Integer) obj) > ((Integer) arg1)) && (((Integer) obj) < ((Integer) arg2));
        } else if (d.toString().equals("BigInteger")) {
            return (((Long) obj) > ((Long) arg1)) && (((Long) obj) < ((Long) arg2));
        } else if (d.toString().equals("String")) {
            return (((String) obj).compareTo((String) arg1) > 0) && (((String) obj).compareTo((String) arg2) < 0);
        } else if (d.toString().equals("Numeric")) {
            return (((BigDecimal) obj).compareTo((BigDecimal) arg1) > 0) && (((BigDecimal) obj).compareTo((BigDecimal) arg2) < 0);
        } else if (d.toString().equals("DateTime")) {
            return (((Date) obj).compareTo((Date) arg1) > 0) && (((Date) obj).compareTo((Date) arg2) < 0);
        } else {
            return false;
        }
    }
}
